<template>
  <div v-loading="loading" :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
import china from 'echarts/map/json/china.json'
import resize from './mixins/resize'

require('echarts/theme/macarons') // echarts theme

echarts.registerMap('china', china)
export default {
  mixins: [resize],
  props: {
    className: {
      type: String,
      default: 'gpsChart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '600px'
    }
  },
  data() {
    return {
      loading: true,
      center: [],
      maxDist: '',
      allList: [], // 所有设备
      normalList: [], // 正常设备
      statusList: [], // 开启设备
      onlineList: [], // 在线设备
      alarmList: [], // 报警设备
      chart: null
    }
  },
  watch: {
    'loading': {
      handler() {
        this.initChart()
      }
    }
  },
  beforeDestroy() {
    this.destroyChart()
  },
  methods: {
    handleRefresh(gps) { // 刷新地图
      this.loading = true
      // console.log('gps', gps)
      const ls = gps.deviceGpsVOList
      this.center.push(gps.center.longitude, gps.center.latitude)
      this.allList = this.convertData(ls)
      this.maxDist = gps.maxDist
      this.normalList = this.convertData(ls, 'normal')
      this.statusList = this.convertData(ls, 'status')
      this.onlineList = this.convertData(ls, 'online')
      this.alarmList = this.convertData(ls, 'alarmLevel')
      this.loading = false
    },
    initChart() {
      this.chart = echarts.init(this.$el, 'macarons')
      const option = this.getOptions()
      this.chart.setOption(option)
    },
    getOptions() {
      const zoom = this.getZoom()
      return {
        title: {
          text: '设备GPS定位信息 - 实时',
          left: 'center',
          textStyle: {
            color: '#000'
          }
        },
        tooltip: {
          trigger: 'item',
          formatter: (params) => {
            const all = params.data.all
            const marker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + params.color + ';"></span>'
            const statusMarker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + this.getStateColor(all.alarmLevel) + ';"></span>'
            let s = ''
            if (all.alarmLevel) s = '出现报警'
            else if (!all.status) s = '未开启'
            else if (!all.online) s = '离线'
            else s = '正常运行'
            // console.log('st', params, s, all)
            return marker + `
            设备名: ${all.deviceName}<br>
            报警ID: ${all.deviceId}&emsp;设备号: ${all.number}<br>
            状态: ` + statusMarker + `${s}<br>
            位置(经纬度): (${this.fixed(all.lon, 7)}, ${this.fixed(all.lat, 7)})
            `
          }
        },
        geo: {
          map: 'china',
          roam: true, // 一定要关闭拖拽
          zoom: zoom,
          center: this.center, // 调整地图位置
          label: {
            normal: {
              show: false, // 关闭省份名展示
              fontSize: '10',
              color: 'rgba(0,0,0,0.7)'
            },
            emphasis: {
              show: false
            }
          },
          itemStyle: {
            normal: {
              areaColor: 'transparent',
              borderColor: '#389dff',
              borderWidth: 1, // 设置外层边框
              shadowBlur: 5,
              shadowOffsetY: 8,
              shadowOffsetX: 0,
              shadowColor: '#01012a'
            },
            emphasis: {
              areaColor: 'rgba(168,150,36,0.89)',
              shadowOffsetX: 0,
              shadowOffsetY: 0,
              shadowBlur: 5,
              borderWidth: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        },
        legend: {
          data: ['所有设备', '开启设备', '在线设备', '正常运转', '报警设备'],
          orient: 'vertical', // 垂直显示
          y: 'top', // 延Y轴居中
          x: 'right' // 居右显示
        },
        series: [
          {
            name: '所有设备',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: this.allList,
            symbolSize: function(val) {
              return 2
            },
            encode: { value: 2 },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: false
            },
            itemStyle: {
              color: '#37c8e1',
              shadowBlur: 10,
              shadowColor: '#000'
            },
            zlevel: 1
          },
          {
            name: '开启设备',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: this.statusList,
            symbolSize: function(val) {
              return 4
            },
            encode: { value: 2 },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: true
            },
            itemStyle: {
              color: '#28d9af',
              shadowBlur: 10,
              shadowColor: '#000'
            },
            zlevel: 2
          },
          {
            name: '在线设备',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: this.onlineList,
            symbolSize: function(val) {
              return 4
            },
            encode: { value: 2 },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: true
            },
            itemStyle: {
              color: '#37c8e1',
              shadowBlur: 10,
              shadowColor: '#000'
            },
            zlevel: 3
          },
          {
            name: '正常运转',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: this.normalList,
            symbolSize: function(val) {
              return 5
            },
            encode: { value: 2 },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: true
            },
            itemStyle: {
              color: 'rgb(164,245,123)',
              shadowBlur: 10,
              shadowColor: '#000'
            },
            zlevel: 4
          },
          {
            name: '报警设备',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: this.alarmList,
            symbolSize: function(val) {
              return (val[2] <= 2) ? 5 : val[2] * 2
            },
            encode: { value: 2 },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              formatter: '{b}',
              position: 'right',
              show: true
            },
            itemStyle: {
              color: '#c72f14',
              shadowBlur: 10,
              shadowColor: '#000'
            },
            zlevel: 5
          }
        ]
      }
    },
    fixed(_m_, _n_ = 2) { // 保留n位小数，向下取整
      const num = Number(_m_)
      const n = Number(_n_)
      // 都是数字才执行
      if (!isNaN(num) && !isNaN(n)) {
        // 原始数字先放大10的n次方倍，并取出整数部分
        // 紧接着字符串展开成数组
        const list = [...Math.floor(num * 10 ** n).toString()]
        // 在数组的倒数第n位插入一个小数点
        list.splice(-n, 0, '.')
        return list.join('')// 数组转字符串，返回
      }
      return '0.00'// 默认返回值
    },
    getStateColor(alarmLevel) {
      if (alarmLevel === 0) return '#9ee33b'
      if (alarmLevel < 3) return '#3BA1DE'
      if (alarmLevel < 5) return '#E1A128'
      if (alarmLevel < 8) return '#E32B3C'
    },
    getZoom() { // 计算缩放比例
      const maxDistance = this.maxDist * 2// 计算距离中心点最远点和中心点距离的2倍
      const zoom = ['50', '100', '200', '500', '1000', '2000', '5000', '10000', '20000', '25000', '50000', '100000', '200000',
        '500000', '1000000', '2000000', '4000000', '8000000', '16000000'] // 级别18到3。
      for (let i = 0, zoomLen = zoom.length; i < zoomLen; i++) {
        if (zoom[i] - maxDistance > 0) {
          // console.log('zoom', i, zoom[i])
          return 18 - i
        }
      }
    },
    convertData(data, filter) {
      const res = []
      if (!filter) filter = ''
      for (const vo of data) {
        let flag
        if (!filter) flag = true
        else if (vo[filter]) {
          if (filter === 'alarmLevel' && vo[filter] > 0) flag = true
          else if (filter === 'normal' && vo[filter]) flag = true
          else if (filter === 'status' && vo[filter]) flag = true
          else if (filter === 'online' && vo[filter]) flag = true
          else flag = false
        } else flag = false
        if (flag) {
          res.push({
            name: vo.deviceName,
            value: [vo.lon, vo.lat, vo.alarmLevel],
            all: vo
          })
        }
      }
      return res
    },
    destroyChart() {
      if (!this.chart) return
      this.chart.dispose()
      this.chart = null
    }
  }
}
</script>

<style scoped>

</style>
